package com.utility.project.common.utils;

import com.utility.project.common.base.R;
import com.utility.project.common.constants.HttpCodeEnum;
import io.jsonwebtoken.*;

import java.util.Calendar;
import java.util.Date;

/**
 * @author liujinchao
 * @date 2022/12/20 17:03
 * @description JWT工具类
 */
public class JwtUtil {

    /** JWT秘钥 */
    public final static String SECRET_KEY = "someday";

    /** 过期时间天数 */
    public final static int EXPIRE_DAY = 7;

    private final static String USERNAME_SIGN = "username";

    /**
     * 身份认证
     * @param jwt 令牌
     * @return 成功状态返回200，其它均为失败
     */
    public static R validationToken(String jwt) {
        try {
            //解析JWT字符串中的数据，并进行最基础的验证
            Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(jwt)
                .getBody();
            String username = claims.get(USERNAME_SIGN).toString();
            return R.ok(username);
        } catch (ExpiredJwtException e) {
            // 已过期令牌
            return R.fail(HttpCodeEnum.AUTH_EXPIRED.getCode(),HttpCodeEnum.AUTH_EXPIRED.getMessage());
        } catch (SignatureException e) {
            // 伪造令牌
            return R.fail(HttpCodeEnum.UNAUTHORIZED.getCode(),HttpCodeEnum.UNAUTHORIZED.getMessage());
        } catch (Exception e) {
            // 系统错误
            return R.fail(HttpCodeEnum.UNAUTHORIZED.getCode(),HttpCodeEnum.UNAUTHORIZED.getMessage());
        }
    }

    /**
     * 构建JWT对象
     * @param username 用户名
     * @return
     */
    public static String buildJwt(String username) {
        Date expire = getLoginExpireTime();
        String jwt = Jwts.builder()
                // 使用HS256加密算法
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                // 过期时间
                .setExpiration(expire)
                .claim(USERNAME_SIGN,username)
                .compact();
        return jwt;
    }

    /**
     * 获取登陆过期时间
     *
     * @return
     */
    private static Date getLoginExpireTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, EXPIRE_DAY);
        return calendar.getTime();
    }

}
